#include "adc_oneshot.h"



const static char *TAG = "ADC1_CHAN4";

// ADC校准是否成功标准
bool do_calibration1_chan4 = false;
// ADC校准结构体初始化
//adc_cali_handle_t adc1_cali_chan4_handle;


static bool adc_calibration_init(adc_cali_handle_t *out_handle);


/**
* @brief 有关ADC1进行初始化，该初始化为单通道采样
* @param[in] adc1_handle 单次ADC采样句柄
* @return -1:handle is NULL
*          >=0: ADC 电压值(单位mv)
*/
int adc1_read_voltage_val(adc_oneshot_unit_handle_t* adc1_handle, adc_cali_handle_t* adc1_cali_chan4_handle)
{
    if(adc1_handle == NULL || adc1_cali_chan4_handle == NULL){
        ESP_LOGI(TAG, "handle is NULL");
        return -1;
    }

    int adc_raw, adc_voltage;
    ESP_ERROR_CHECK(adc_oneshot_read(*adc1_handle, ADC1_CHAN4, &adc_raw));
    
    if (do_calibration1_chan4) {
        ESP_ERROR_CHECK(adc_cali_raw_to_voltage(*adc1_cali_chan4_handle, adc_raw, &adc_voltage));
        // ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", UINT_ADC_ID + 1, ADC1_CHAN4, adc_voltage);
    }

    return adc_voltage;
}

// ADC进行校准
static bool adc_calibration_init(adc_cali_handle_t *out_handle)
{
    adc_cali_handle_t handle = NULL;
    esp_err_t ret = ESP_FAIL;
    bool calibrated = false;

#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
    if (!calibrated) {
        ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting");
        adc_cali_curve_fitting_config_t cali_config = {
            .unit_id = UINT_ADC_ID,
            .atten = ADC_ATTEN,
            .bitwidth = ADC_BITWIDTH_DEFAULT,
        };
        ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
        if (ret == ESP_OK) {
            calibrated = true;
        }
    }
#endif

#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
    if (!calibrated) {
        ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting");
        adc_cali_line_fitting_config_t cali_config = {
            .unit_id = UINT_ADC_ID,
            .atten = ADC_ATTEN,
            .bitwidth = ADC_BITWIDTH_DEFAULT,
        };
        ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
        if (ret == ESP_OK) {
            calibrated = true;
        }
    }
#endif

    *out_handle = handle;
    if (ret == ESP_OK) {
        ESP_LOGI(TAG, "Calibration Success");
    } else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
        ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
    } else {
        ESP_LOGE(TAG, "Invalid arg or no memory");
    }

    return calibrated;
}


/**
* @brief 有关ADC1进行初始化，该初始化为单通道采样
* @param[in] adc1_handle 单次ADC采样句柄
* @param[in] adc1_cali_chan4_handle 单次ADC校准句柄
* @param[out] adc1_handle 被修改后的单次ADC采样句柄，一定会使用到
* @param[out] adc1_cali_chan4_handle 被修改后的单次ADC校准句柄，一定会使用到
* @return NULL
*/
void adc1_init(adc_oneshot_unit_handle_t* adc1_handle, adc_cali_handle_t* adc1_cali_chan4_handle)
{
    // ADC 选择配置
    adc_oneshot_unit_init_cfg_t init_config1 = {
        .unit_id = UINT_ADC_ID,
        .ulp_mode = ADC_ULP_MODE_DISABLE,
    };
    ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, adc1_handle));

    adc_oneshot_chan_cfg_t config = {
        .bitwidth = ADC_BITWIDTH_DEFAULT,
        .atten = ADC_ATTEN,
    };

    ESP_ERROR_CHECK(adc_oneshot_config_channel(*adc1_handle, ADC1_CHAN4, &config));
    // ADC1通道4的校准初始化
    do_calibration1_chan4 = adc_calibration_init(adc1_cali_chan4_handle);
}